#include<iostream>
#include<vector>
#include<ctime>
#include<string>
#include<unistd.h>
#include"Thread.hpp"
#include"LockGuard.hpp"
using namespace ThreadMoudle;

//全局资源：
int ticket = 1200;
//10.定义一个全局的条件变量：
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

//3.定义一个抢票的函数：
void bagTicket(const ThreadData* atr)
{
    ThreadData* tmp= (ThreadData*)atr;
    while(true)
    {
        //6.加锁，解锁一气呵成：while循环一进来就给你创建Lock对象加锁，一结束就销毁对象解锁！（RAII风格）
        Lock tmplock(tmp->_lock);//注意：这里要求是有名对象，不能是匿名对象
        //11.将子线程加入到等待队列中：
        pthread_cond_wait(&cond, tmp->_lock);//如果没有其他线程唤醒它们，它们将一直再等待：
        if(ticket > 0)
        {
            usleep(1000);//这里相当于1ms，即抢票需要花费的时间
            printf("%s get a ticket: %d\n", tmp->_name.c_str(), ticket);
            ticket--;
        }
        else
        {
            std::cout << "no ticket!!!" << std::endl;
            break;
        }
    }
}

int main()
{
    //1.创建局部锁：
    pthread_mutex_t lock;
    pthread_mutex_init(&lock, nullptr);

    int begin = 0, end = 0;
    std::vector<Thread> vt;
    for(int i=0; i<4; i++)
    {
        //2.创建线程：
        std::string name  = "thread-" + std::to_string(i+1);
        ThreadData td(name, &lock);
        Thread t(td, bagTicket);
        vt.push_back(t);
    }

    for(auto& k : vt)
    {
        //4.启动线程：
        usleep(10000);
        k.Start();
    }

    //12。唤醒线程：
    while(ticket > 0)
    {
        pthread_cond_signal(&cond);
    }
    sleep(1);
    pthread_cond_broadcast(&cond);

    for(auto& k : vt)
    {
        //8.等待线程：
        k.Join();
    }
    end = clock();
    //9.销毁锁：
    pthread_mutex_destroy(&lock);
    std::cout << "整个过程耗时->" << end-begin << "ms" <<std::endl;
    return 0;
}